﻿#region Copyright Notice
// 
// 
//  
//  Copyright (c) 2009-2011 Anindya Chatterjee
//  
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//  
//      http://www.apache.org/licenses/LICENSE-2.0
//  
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
// 
// 
#endregion
using System;
using System.Linq;
using AbstractClass.Collections.Generic;
using AbstractClass.Linq;
using NUnit.Framework;

namespace QuasarTest.Core
{
    [TestFixture]
    public class HeapTest
    {
        #region Setup/Teardown

        [SetUp]
        public void Init()
        {
            _heapMin = new Heap<int>(HeapType.Minimum);
            _heapMax = new Heap<int>(HeapType.Maximum);

            Enumerable.Range(0, 20).Process(_heapMin.Add);
            Enumerable.Range(0, 20).Process(_heapMax.Add);
        }

        #endregion

        private Heap<int> _heapMin;
        private Heap<int> _heapMax;


        [Test]
        public void TestAdd()
        {
            _heapMin.Add(20);
            Assert.IsTrue(_heapMin.Contains(20));
            _heapMax.Add(20);
            Assert.IsTrue(_heapMax.Contains(20));
            Assert.AreEqual(_heapMin.Count, 21);
            Assert.AreEqual(_heapMax.Count, 21);
        }

        [Test]
        public void TestClear()
        {
            Assert.AreEqual(_heapMin.Count, 20);
            _heapMin.Clear();
            Assert.AreEqual(_heapMin.Count, 0);
            Assert.AreEqual(_heapMax.Root, 19);
            _heapMax.Clear();
            Assert.Throws(typeof (InvalidOperationException), () => Assert.AreEqual(_heapMax.Root, 0));
        }

        [Test]
        public void TestCopyTo()
        {
            var arrMin = (int[]) Array.CreateInstance(typeof (int), 20);
            var arrMax = (int[]) Array.CreateInstance(typeof (int), 20);
            Assert.IsFalse(_heapMax.All(x => arrMax.Contains(x)));
            _heapMin.CopyTo(arrMin, 0);
            _heapMax.CopyTo(arrMax, 0);

            Assert.IsTrue(_heapMin.All(x => arrMin.Contains(x)));
            Assert.IsTrue(_heapMax.All(x => arrMax.Contains(x)));
        }

        [Test]
        public void TestMerge()
        {
            Assert.Throws(typeof (ArgumentException), () => _heapMax.Merge(_heapMin));
            var heap = new Heap<int>(HeapType.Minimum);
            Enumerable.Range(30, 10).Process(heap.Add);

            Assert.AreEqual(heap.Root, 30);
            Assert.AreEqual(heap.Count, 10);

            heap.Merge(_heapMin);

            Assert.AreEqual(heap.Root, 0);
            Assert.AreEqual(heap.Count, 30);
            Assert.AreEqual(_heapMin.Count, 20);
        }

        [Test]
        public void TestRemove()
        {
            int root = _heapMin.Root;
            Assert.AreEqual(_heapMin.Count, 20);
            Assert.AreEqual(root, _heapMin.RemoveItem());
            Assert.AreEqual(_heapMin.Count, 19);
            root = _heapMin.Root;
            Assert.AreEqual(root, _heapMin.RemoveItem());
            Assert.AreEqual(_heapMin.Count, 18);
        }
    }
}